﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using Aspose.Cells;
using Aspose.Cells.Drawing;
using Tilver.Configuration;
using Tilver.Configuration.Data;

namespace Weixin.MP.UI
{
    public static class Common
    {
        /// <summary>
        /// md5签名密钥
        /// </summary>
        public const string MD5Key = "A*l{10>Gk5!m";
        /// <summary>
        /// 验证码SESSION名称
        /// </summary>
        public const string VerifyCodeSession = "VerifyCode";
        /// <summary>
        /// 当前登陆用户SESSION
        /// </summary>
        public const string LoginUserSession = "LoginUser";
        /// <summary>
        /// 微信菜单数据
        /// </summary>
        public const string WeixinMenu = "Sys_WeixinMenu";
        /// <summary>
        /// 默认分页大小
        /// </summary>
        public const int DefaultPageSize = 20;
        /// <summary>
        /// 公众号应用ID
        /// </summary>
        public static string AppId { get { return ConfigurationManager.AppSettings.AllKeys.Contains("AppId") ? ConfigurationManager.AppSettings["AppId"] : ""; } }
        /// <summary>
        /// 公众号应用密钥
        /// </summary>
        public static string AppSecret { get { return ConfigurationManager.AppSettings.AllKeys.Contains("AppSecret") ? ConfigurationManager.AppSettings["AppSecret"] : ""; } }
        /// <summary>
        /// 微信接口签名密钥
        /// </summary>
        public static string AppToken { get { return ConfigurationManager.AppSettings.AllKeys.Contains("AppToken") ? ConfigurationManager.AppSettings["AppToken"] : ""; } }


        #region DefaultDateTime
        /// <summary>
        /// 获取日期对象的系统默认值。
        /// </summary>
        public static DateTime DefaultDateTime { get { return default(DateTime); } }
        #endregion

        #region IsNullOrDBNull
        /// <summary>
        /// 对象是否为 null 或 DBNull 。
        /// </summary>
        /// <param name="value">要判断的对象。</param>
        public static bool IsNullOrDBNull(this object value)
        {
            return value == null || value is DBNull;
        }
        #endregion

        #region IsSafeSQL


        /// <summary>
        /// 检测是否有Sql危险字符
        /// </summary>
        /// <param name="str">要判断字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsSafeSqlString(string str)
        {
            return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }
        #endregion

        #region IsIP


        /// <summary>
        /// 是否为ip地址
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }
        #endregion

        #region IsMobile
        /*
        我国使用的手机号码为11位，其中各段有不同的编码方向：前3位———网络识别号；第4-7位———地区编码；第8-11位———用户号码。
        130至132号段为联通手机号段；133号段为电信手机号段；中国移动占有其余6个子号段，由134至139号段。按照电信号码使用的原则，一般达到理论容量的50%，即意味着号码资源利用率接近饱和了。按照中国移动现有6个号段分析，移动的用户号码容量实际上限应该在3亿左右；而联通的上限在2亿上下。而电信的上限在1亿上下。
        电信
        中国电信手机号码开头数字 133、153、180、181、189
        联通
        中国联通手机号码开头数字 130、131、132、145、155、156、185、186
        移动
        中国移动手机号码开头数字 134、135、136、137、138、139、147、150、151、152、157、158、159、182、183、184、187、188
        补充
        14开头的号码以前为上网卡专属号段，如联通的是145，移动的是147等等。
        移动为3G启用的号段187.188，联通是186和185号段，电信的号段则是180和189. 
         */
        /// <summary>
        /// 结定的字符串是否为手机号码。
        /// </summary>
        /// <param name="mobile">要判断的字符串。</param>
        public static bool IsMobile(string mobile)
        {
            if (string.IsNullOrEmpty(mobile)) return false;
            return Regex.IsMatch(mobile, @"^(?:13|14|15|18)[0-9]{9}$", RegexOptions.IgnoreCase);
        }
        #endregion

        #region IsNumeric
        /// <summary>
        /// 判断给定的字符串是否为数值类型（整数及小数）。
        /// </summary>
        /// <param name="value">要检测的字符串。</param>
        public static bool IsNumeric(String value)
        {
            //n次匹配有什么意义？？
            //@:???
            //-:???
            //+:一次或多次匹配前面的字符或子表达式??
            //?:零次或一次匹配前面的字符或子表达式
            //*:零次或多次匹配前面的字符或子表达式
            //\b:匹配一个字边界，即字与空格间的位置  ？？
            //.:匹配除“\n”之外的任何单个字符。
            return Regex.IsMatch(value, @"[-+]?\b[0-9]*\.?[0-9]+\b");
        }
        #endregion

        #region IsInteger
        /// <summary>
        /// 判断给定的字符串是否为数值类型（整数）。
        /// </summary>
        /// <param name="value">要检测的字符串。</param>
        public static bool IsInteger(String value)
        {
            //\d:数字字符匹配。等效于 [0-9]。 
            return Regex.IsMatch(value, @"^[-+]?\d+$");
        }
        #endregion

        #region IsLetter
        /// <summary>
        /// 字母、数字或 下划线
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsLetterOrNumberOrUnderline(string value)
        {
            return Regex.IsMatch(value, @"^\w+$");
        }

        /// <summary>
        /// 判断给定的字符串是否字母或数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsLetterOrNumber(string value)
        {
            return Regex.IsMatch(value, @"^[A-Za-z0-9]+$");
        }
        /// <summary>
        /// 判断给定的字符串是否仅包含字母。
        /// </summary>
        /// <param name="value">要检测的字符串。</param>
        public static bool IsLetter(string value)
        {
            return Regex.IsMatch(value, "^[a-z]+$", RegexOptions.IgnoreCase);
        }
        #endregion

        #region IsDateTime
        /// <summary>
        /// 判断给定的字符串是否为日期型。
        /// </summary>
        /// <param name="value">要检测的字符串。</param>
        public static bool IsDateTime(String value)
        {
            DateTime d = DateTime.Now;
            if (DateTime.TryParse(value, out d)) return true;
            return false;
        }
        #endregion

        #region IsEmail
        /// <summary>
        /// 给定的字符串是否为电子邮件格式。
        /// </summary>
        /// <param name="email">要判断的字符串。</param>
        public static bool IsEmail(String email)
        {
            if (string.IsNullOrEmpty(email)) return false;
            return Regex.IsMatch(email, @"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.(?:com|org|net|gov|biz|info|name|aero|mobi|jobs|museum|asia|[A-Z]{2})$", RegexOptions.IgnoreCase);
        }
        #endregion

        #region ToString
        /// <summary>
        /// 将对象转换为字符串。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        public static String ToString(object value)
        {
            if (value.IsNullOrDBNull()) return String.Empty;
            return String.IsNullOrEmpty(value.ToString()) ? String.Empty : value.ToString();
        }
        #endregion

        #region ToStringTrim
        /// <summary>
        /// 将对象转换为字符串，同时去除首尾空格。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        public static String ToStringTrim(this object value)
        {
            return ToString(value).Trim();
        }
        #endregion

        #region ToLowerCase
        /// <summary>
        /// 将字符串转换为小写形式。
        /// </summary>
        /// <param name="value">待转换的字符串。</param>
        public static String ToLowerCase(this String value)
        {
            if (string.IsNullOrEmpty(ToStringTrim(value))) return value;
            return value.ToLower(System.Globalization.CultureInfo.CurrentCulture);
        }
        #endregion

        #region ToUpperCase
        /// <summary>
        /// 将字符串转换为大写形式。
        /// </summary>
        /// <param name="value">待转换的字符串。</param>
        public static String ToUpperCase(this String value)
        {
            if (string.IsNullOrEmpty(ToStringTrim(value))) return value;
            return value.ToUpper(System.Globalization.CultureInfo.CurrentCulture);
        }
        #endregion

        #region ToByte
        public static Byte ToByte(this string value, byte defaultValue = 0)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                byte _value = 0;
                if (!byte.TryParse(value, out _value)) _value = defaultValue;
                return _value;
            }
            catch
            {
                return defaultValue;
            }
        }
        #endregion

        #region ToInt
        public static Int32 ToInt(this string value, Int32 defaultValue = 0)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                Int32 _value = 0;
                if (!Int32.TryParse(value.ToString(), out _value)) _value = defaultValue;
                return _value;
            }
            catch { return defaultValue; }
        }
        /// <summary>
        /// 将可能为 Int32 类型的对象转换为 Int32 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        /// <param name="defaultValue">转换失败的默认值。</param>
        public static Int32 ToInt(object value, Int32 defaultValue)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                Int32 _value = 0;
                if (!Int32.TryParse(value.ToString(), out _value)) _value = defaultValue;
                return _value;
            }
            catch { return defaultValue; }
        }
        /// <summary>
        /// 将可能为 Int32 类型的对象转换为 Int32 ，转换失败返回 0 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        public static Int32 ToInt(object value)
        {
            return ToInt(value, 0);
        }
        /// <summary>
        /// 将逻辑值转换为 0 或 1 。
        /// </summary>
        /// <param name="value">逻辑值。</param>
        public static Int32 ToInt(this bool value)
        {
            return value ? 1 : 0;
        }
        #endregion

        #region ToInt64
        public static Int64 ToInt64(this string value)
        {
            return ToInt64(value, 0);
        }
        /// <summary>
        /// 将可能为 Int64 类型的对象转换为 Int64 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        /// <param name="defaultValue">转换失败的默认值。</param>
        public static Int64 ToInt64(object value, Int64 defaultValue)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                Int64 _value = 0;
                if (!Int64.TryParse(value.ToString(), out _value)) _value = defaultValue;
                return _value;
            }
            catch { return defaultValue; }
        }
        /// <summary>
        /// 将可能为 Int64 类型的对象转换为 Int64 ，转换失败返回 0 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        public static Int64 ToInt64(object value)
        {
            return ToInt64(value, 0);
        }
        #endregion

        #region ToDecimal
        /// <summary>
        /// 将可能为 Decimal 类型的对象转换为 Decimal 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        /// <param name="defaultValue">转换失败的默认值。</param>
        public static Decimal ToDecimal(object value, Decimal defaultValue)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                Decimal _value = 0;
                if (!Decimal.TryParse(value.ToString(), out _value)) _value = defaultValue;
                return _value;
            }
            catch { return defaultValue; }
        }
        #endregion

        #region ToDateTime
        /// <summary>
        /// 将可能是日期的对象转换为日期。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        /// <param name="defaultValue">转换失败的默认值。</param>
        public static DateTime ToDateTime(object value, DateTime defaultValue)
        {
            try
            {
                if (value.IsNullOrDBNull()) return defaultValue;
                DateTime _value = default(DateTime);

                if (!DateTime.TryParse(value.ToString(), out _value)) _value = defaultValue;
                return _value;
            }
            catch { return defaultValue; }
        }
        /// <summary>
        /// 将可能是日期的对象转换为日期，转换失败返回 default(DateTime) 。
        /// </summary>
        /// <param name="value">待转换的对象（可处理 null 或 DBNull）。</param>
        public static DateTime ToDateTime(object value)
        {
            return ToDateTime(value, DefaultDateTime);
        }
        #endregion

        #region ToMD5
        /// <summary>
        /// 将给定的字符串进行 md5 加密，并返回小写形式的结果。
        /// </summary>
        /// <param name="valueToEncrypt">要加密的字符串。</param>
        public static string ToMD5(this String valueToEncrypt)
        {
            return ToLowerCase(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(valueToEncrypt, "md5"));
        }
        #endregion

        #region URL字符串参数解析


        ///<summary>
        ///将查询字符串解析转换为名值集合.
        ///</summary>
        ///<param name="queryString"></param>
        ///<returns></returns>
        public static NameValueCollection GetQueryURL(string queryString)
        {
            return GetQueryURL(queryString, null, true);
        }

        ///<summary>
        ///将查询字符串解析转换为名值集合.
        ///</summary>
        ///<param name="queryString"></param>
        ///<param name="encoding"></param>
        ///<param name="isEncoded"></param>
        ///<returns></returns>
        public static NameValueCollection GetQueryURL(string queryString, Encoding encoding, bool isEncoded)
        {
            queryString = queryString.Replace("?", "");
            NameValueCollection result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
            if (!string.IsNullOrEmpty(queryString))
            {
                int count = queryString.Length;
                for (int i = 0; i < count; i++)
                {
                    int startIndex = i;
                    int index = -1;
                    while (i < count)
                    {
                        char item = queryString[i];
                        if (item == '=')
                        {
                            if (index < 0)
                            {
                                index = i;
                            }
                        }
                        else if (item == '&')
                        {
                            break;
                        }
                        i++;
                    }
                    string key = null;
                    string value = null;
                    if (index >= 0)
                    {
                        key = queryString.Substring(startIndex, index - startIndex);
                        value = queryString.Substring(index + 1, (i - index) - 1);
                    }
                    else
                    {
                        key = queryString.Substring(startIndex, i - startIndex);
                    }
                    if (isEncoded)
                    {
                        result[MyUrlDeCode(key, encoding)] = MyUrlDeCode(value, encoding);
                    }
                    else
                    {
                        result[key] = value;
                    }
                    if ((i == (count - 1)) && (queryString[i] == '&'))
                    {
                        result[key] = string.Empty;
                    }
                }
            }
            return result;
        }

        ///<summary>
        ///解码URL.
        ///</summary>
        ///<param name="encoding">null为自动选择编码</param>
        ///<param name="str"></param>
        ///<returns></returns>
        private static string MyUrlDeCode(string str, Encoding encoding)
        {
            if (encoding == null)
            {
                Encoding utf8 = Encoding.UTF8;
                //首先用utf-8进行解码                    
                string code = HttpUtility.UrlDecode(str.ToUpper(), utf8);
                //将已经解码的字符再次进行编码.
                string encode = HttpUtility.UrlEncode(code, utf8).ToUpper();
                if (str == encode)
                    encoding = Encoding.UTF8;
                else
                    encoding = Encoding.GetEncoding("gb2312");
            }
            return HttpUtility.UrlDecode(str, encoding);
        }
        #endregion

        #region 获取IP地址
        public static string GetServerIP()
        {
            return HttpContext.Current.Request.ServerVariables.Get("Local_Addr").ToString();
        }
        /// <summary>
        /// 获得当前页面客户端的IP
        /// </summary>
        /// <returns>当前页面客户端的IP</returns>
        public static string GetClientIP()
        {
            string result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.UserHostAddress;
            }
            if (string.IsNullOrEmpty(result) || !IsIP(result))
            {
                return "127.0.0.1";
            }
            return result;
        }
        #endregion

        #region Request
        /// <summary>
        /// 获得指定Url参数的值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <returns>Url参数的值</returns>
        public static string GetQueryString(string strName)
        {
            return GetQueryString(strName, false);
        }
        /// <summary>
        /// 获得指定Url参数的值
        /// </summary> 
        /// <param name="strName">Url参数</param>
        /// <param name="sqlSafeCheck">是否进行SQL安全检查</param>
        /// <returns>Url参数的值</returns>
        public static string GetQueryString(string strName, bool sqlSafeCheck)
        {
            if (HttpContext.Current.Request.QueryString[strName] == null) { return ""; }
            if (sqlSafeCheck && !IsSafeSqlString(HttpContext.Current.Request.QueryString[strName])) { return ""; }
            return HttpContext.Current.Request.QueryString[strName];
        }
        /// <summary>
        /// 获得指定表单参数的值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <returns>表单参数的值</returns>
        public static string GetFormString(string strName)
        {
            return GetFormString(strName, false);
        }

        /// <summary>
        /// 获得指定表单参数的值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="sqlSafeCheck">是否进行SQL安全检查</param>
        /// <returns>表单参数的值</returns>
        public static string GetFormString(string strName, bool sqlSafeCheck)
        {
            if (HttpContext.Current.Request.Form[strName] == null) { return ""; }
            if (sqlSafeCheck && !IsSafeSqlString(HttpContext.Current.Request.Form[strName])) { return ""; }
            return HttpContext.Current.Request.Form[strName];
        }

        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">参数</param>
        /// <returns>Url或表单参数的值</returns>
        public static string GetString(string strName)
        {
            return GetString(strName, false);
        }

        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">参数</param>
        /// <param name="sqlSafeCheck">是否进行SQL安全检查</param>
        /// <returns>Url或表单参数的值</returns>
        public static string GetString(string strName, bool sqlSafeCheck)
        {
            if (string.IsNullOrEmpty(GetQueryString(strName)))
            {
                return GetFormString(strName, sqlSafeCheck);
            }
            else
            {
                return GetQueryString(strName, sqlSafeCheck);
            }
        }

        /// <summary>
        /// 获得当前完整Url地址
        /// </summary>
        /// <returns>当前完整Url地址</returns>
        public static string GetRequestUrl()
        {
            return HttpContext.Current.Request.Url.ToString();
        }
        /// <summary>
        /// 获得当前页面的名称
        /// </summary>
        /// <returns>当前页面的名称</returns>
        public static string GetPageName()
        {
            string[] urlArr = HttpContext.Current.Request.Url.AbsolutePath.Split('/');
            return urlArr[urlArr.Length - 1].ToLower();
        }
        /// <summary>
        /// 获取站点根目录虚拟路径
        /// </summary>
        /// <returns></returns>
        public static string GetRootUrl(string forumPath)
        {
            int port = HttpContext.Current.Request.Url.Port;
            return string.Format("{0}://{1}{2}{3}",
                                 HttpContext.Current.Request.Url.Scheme,
                                 HttpContext.Current.Request.Url.Host.ToString(),
                                 (port == 80 || port == 0) ? "" : ":" + port,
                                 forumPath);
        }
        /// <summary>
        /// 获取站点根目录的物理路径
        /// </summary>
        /// <returns></returns>
        public static string GetPhysicalRootPath()
        {
            return HttpContext.Current.Request.PhysicalApplicationPath;
        }
        #endregion

        #region 文件操作
        public static OperationResult<DataTable> GetDataFromExcel(string filePath)
        {
            try
            {
                if (string.IsNullOrEmpty(filePath))
                {
                    return new OperationResult<DataTable>() { State = 1, Message = "请选择上传文件" };
                }
                var fileName = HttpContext.Current.Server.MapPath(filePath);
                if (!File.Exists(fileName))
                {
                    return new OperationResult<DataTable>() { State = 1, Message = "请选择上传文件" };
                }
                string error;
                var dt = new DataTable();
                if (!ExcelFileToDataTable(fileName, out dt, out error))
                {
                    return new OperationResult<DataTable>() { State = 4, Message = error };
                }
                //删除上传的临时文件
                DeleteFile(fileName);
                return new OperationResult<DataTable>() { State = 0, Message = "ok", Value = dt };
            }
            catch (Exception ex)
            {
                return new OperationResult<DataTable>() { State = -1, Message = ex.Message };
            }
            /*
            try
            {
                //连接串  
                string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + ";" + "Extended Properties=Excel 8.0;HDR=Yes;IMEX=1;";
                var conn = new OleDbConnection(strConn);
                conn.Open();
                //返回Excel的架构，包括各个sheet表的名称,类型，创建时间和修改时间等  
                var dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
                //包含excel中表名的字符串数组  
                string[] strTableNames = new string[dtSheetName.Rows.Count];
                for (int k = 0; k < dtSheetName.Rows.Count; k++)
                {
                    strTableNames[k] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
                }

                OleDbDataAdapter myCommand = null;
                var dt = new DataTable();
                //从指定的表名查询数据,可先把所有表名列出来供用户选择  
                string strExcel = "select * from [" + strTableNames[0] + "]";
                myCommand = new OleDbDataAdapter(strExcel, strConn);
                dt = new DataTable();
                myCommand.Fill(dt);
                conn.Close();
                conn.Dispose();
                //this.GridView1.DataSource = dt;  
                //this.GridView1.DataBind();  
                return new OperationResult<DataTable>() { State = 0, Message = "ok", Value = dt };
            }
            catch (Exception ex)
            {
                return new OperationResult<DataTable>() { State = -1, Message = ex.Message };

            }
            */
        }

        public static string GetFileExt(string fullPath)
        {
            return fullPath != "" ? fullPath.Substring(fullPath.LastIndexOf('.') + 1).ToLower() : "";
        }

        public static void DeleteFile(string fileName)
        {
            if (File.Exists(fileName)) File.Delete(fileName);
        }

        public static void CreateFolder(string folderPath)
        {
            if (!System.IO.Directory.Exists(folderPath)) System.IO.Directory.CreateDirectory(folderPath);
        }
        /// <summary>
        /// 上传FORM表单文件 
        /// </summary>
        /// <param name="inputName">表单文件域名称</param>
        /// <param name="uploadDir">上传文件保存路径，结尾不要带‘/’</param>
        /// <param name="saveType">0: 直接存放 1:按天存入目录 2:按月存入目录 3:按扩展名存目录</param>
        /// <param name="maxSize">最大上传文件大小(byte)</param>
        /// <param name="fileExt">允许上传文件扩展名</param>
        /// <param name="domain">当前域名，空返回相对地址，否则返回绝对地址</param>
        /// <returns></returns>
        public static OperationResult<string> UploadRequestFile(string inputName, string uploadDir, int? saveType = null, int? maxSize = null, string fileExt = null, string domain = null)
        {
            var request = HttpContext.Current.Request;
            string inputname = inputName; //表单文件域name
            string attachdir = uploadDir; //上传文件保存路径，结尾不要带/
            int dirtype = saveType.HasValue ? saveType.Value : 1; //0: 直接存放 1:按天存入目录 2:按月存入目录 3:按扩展名存目录  建议使用按天存
            int maxattachsize = maxSize.HasValue ? maxSize.Value : 200 * 1024; //最大上传文件大小，默认是200K
            string upext = string.IsNullOrEmpty(fileExt) ? "jpg,jpeg,gif,png" : fileExt; // 允许上传文件扩展名
            //int msgtype = 2; //返回上传参数的格式：1，只返回url，2，返回参数数组
            string localdomain = string.IsNullOrEmpty(domain) ? string.Empty : domain;
            byte[] file; // 统一转换为byte数组处理
            string localname; //上传的文件名
            var disposition = request.ServerVariables["HTTP_CONTENT_DISPOSITION"];
            if (disposition != null)
            {
                // HTML5上传
                file = request.BinaryRead(request.TotalBytes);
                localname = HttpContext.Current.Server.UrlDecode(Regex.Match(disposition, "filename=\"(.+?)\"").Groups[1].Value); // 读取原始文件名
            }
            else
            {
                var filecollection = request.Files;
                var postedfile = filecollection.Get(inputname);
                // 读取原始文件名
                localname = postedfile.FileName;
                // 初始化byte长度.
                file = new Byte[postedfile.ContentLength];
                // 转换为byte类型
                System.IO.Stream stream = postedfile.InputStream;
                stream.Read(file, 0, postedfile.ContentLength);
                stream.Close();
            }

            if (file.Length == 0)
            {
                return new OperationResult<string>() { State = 1, Message = "没有提交上传数据", Value = string.Empty };
            }
            else
            {
                if (file.Length > maxattachsize)
                {
                    return new OperationResult<string>() { State = 2, Message = string.Format("文件大小超过系统限制（{0}字节）", maxattachsize) };
                }
                else
                {
                    string attach_dir, attach_subdir, filename, extension, target;
                    // 取上载文件后缀名
                    extension = GetFileExt(localname);
                    if (("," + upext + ",").IndexOf("," + extension + ",") < 0)
                    {
                        return new OperationResult<string>() { State = 3, Message = string.Format("上传文件扩展名必须为：{0}", upext) };
                    }
                    else
                    {
                        switch (dirtype)
                        {
                            case 0:
                                attach_subdir = string.Empty;
                                break;
                            case 1:
                                attach_subdir = DateTime.Now.ToString("yyyyMMdd");
                                break;
                            case 2:
                                attach_subdir = DateTime.Now.ToString("yyyyMM");
                                break;
                            case 3:
                                attach_subdir = extension;
                                break;
                            default:
                                attach_subdir = string.Empty;
                                break;
                        }
                        attach_dir = string.IsNullOrEmpty(attach_subdir) ? string.Format("/{0}/", attachdir) : string.Format("/{0}/{1}/", attachdir, attach_subdir);

                        // 生成随机文件名
                        var random = new Random(DateTime.Now.Millisecond);
                        filename = DateTime.Now.ToString("yyyyMMddHHmmss") + random.Next(10000) + "." + extension;
                        target = attach_dir + filename;
                        try
                        {
                            CreateFolder(HttpContext.Current.Server.MapPath(attach_dir));
                            var fs = new System.IO.FileStream(HttpContext.Current.Server.MapPath(target), System.IO.FileMode.Create,
                                                              System.IO.FileAccess.Write);
                            fs.Write(file, 0, file.Length);
                            fs.Flush();
                            fs.Close();
                            target = localdomain + target;
                        }
                        catch (Exception ex)
                        {
                            return new OperationResult<string>() { State = 4, Message = ex.Message.ToString(CultureInfo.InvariantCulture), Value = string.Empty };
                        }
                        return new OperationResult<string>() { State = 0, Message = "上传成功", Value = target };
                    }
                }
            }

        }
        #endregion

        #region EXCEL操作
        public static bool DataTableToExcel(DataTable datatable, string filepath, out string error)
        {
            error = "";
            try
            {
                if (datatable == null)
                {
                    error = "DataTableToExcel:datatable 为空";
                    return false;
                }

                Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
                Aspose.Cells.Worksheet sheet = workbook.Worksheets[0];
                Aspose.Cells.Cells cells = sheet.Cells;

                int nRow = 0;
                foreach (DataRow row in datatable.Rows)
                {
                    nRow++;
                    try
                    {
                        for (int i = 0; i < datatable.Columns.Count; i++)
                        {
                            if (row[i].GetType().ToString() == "System.Drawing.Bitmap")
                            {
                                //------插入图片数据-------
                                System.Drawing.Image image = (System.Drawing.Image)row[i];
                                MemoryStream mstream = new MemoryStream();
                                image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg);
                                sheet.Pictures.Add(nRow, i, mstream);
                            }
                            else
                            {
                                cells[nRow, i].PutValue(row[i]);
                            }
                        }
                    }
                    catch (System.Exception e)
                    {
                        error = error + " DataTableToExcel: " + e.Message;
                    }
                }

                workbook.Save(filepath);
                return true;
            }
            catch (System.Exception e)
            {
                error = error + " DataTableToExcel: " + e.Message;
                return false;
            }
        }

        public static bool DataTableToExcel2(DataTable datatable, string filepath, out string error)
        {
            error = "";
            Aspose.Cells.Workbook wb = new Aspose.Cells.Workbook();

            try
            {
                if (datatable == null)
                {
                    error = "DataTableToExcel:datatable 为空";
                    return false;
                }

                //为单元格添加样式    
                Aspose.Cells.Style style = wb.Styles[wb.Styles.Add()];
                //设置居中
                style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center;
                //设置背景颜色
                style.ForegroundColor = System.Drawing.Color.FromArgb(153, 204, 0);
                style.Pattern = BackgroundType.Solid;
                style.Font.IsBold = true;

                int rowIndex = 0;
                for (int i = 0; i < datatable.Columns.Count; i++)
                {
                    DataColumn col = datatable.Columns[i];
                    string columnName = col.Caption ?? col.ColumnName;
                    wb.Worksheets[0].Cells[rowIndex, i].PutValue(columnName);
                    //wb.Worksheets[0].Cells[rowIndex, i].Style = style;
                    wb.Worksheets[0].Cells[rowIndex, i].SetStyle(style);
                }
                rowIndex++;

                foreach (DataRow row in datatable.Rows)
                {
                    for (int i = 0; i < datatable.Columns.Count; i++)
                    {
                        wb.Worksheets[0].Cells[rowIndex, i].PutValue(row[i].ToString());
                    }
                    rowIndex++;
                }

                for (int k = 0; k < datatable.Columns.Count; k++)
                {
                    wb.Worksheets[0].AutoFitColumn(k, 0, 150);
                }
                wb.Worksheets[0].FreezePanes(1, 0, 1, datatable.Columns.Count);
                wb.Save(filepath);
                return true;
            }
            catch (Exception e)
            {
                error = error + " DataTableToExcel: " + e.Message;
                return false;
            }

        }

        /// <summary>
        /// Excel文件转换为DataTable.
        /// </summary>
        /// <param name="filepath">Excel文件的全路径</param>
        /// <param name="datatable">DataTable:返回值</param>
        /// <param name="error">错误信息:返回错误信息，没有错误返回""</param>
        /// <returns>true:函数正确执行 false:函数执行错误</returns>
        public static bool ExcelFileToDataTable(string filepath, out DataTable datatable, out string error)
        {
            error = "";
            datatable = null;
            try
            {
                if (File.Exists(filepath) == false)
                {
                    error = "文件不存在";
                    datatable = null;
                    return false;
                }
                var workbook = new Aspose.Cells.Workbook();
                workbook.Open(filepath);
                var worksheet = workbook.Worksheets[0];
                datatable = worksheet.Cells.ExportDataTable(0, 0, worksheet.Cells.MaxRow + 1, worksheet.Cells.MaxColumn + 1);
                //-------------图片处理-------------
                //var pictures = worksheet.Pictures;
                //if (pictures.Count > 0)
                //{
                //    string error2 = "";
                //    if (InsertPicturesIntoDataTable(pictures, datatable, out datatable, out error2) == false)
                //    {
                //        error = error + error2;
                //    }
                //}
                return true;
            }
            catch (System.Exception e)
            {
                error = e.Message;
                return false;
            }

        }



        //public static bool ExcelFileToLists(string filepath, out IList[] lists, out string error)
        //{
        //    error = "";
        //    lists = null;
        //    DataTable datatable = new DataTable();
        //    IList list = new ArrayList();
        //    Pictures[] pictures;
        //    if (ExcelFileToDataTable(filepath, out datatable, out error) && GetPicturesFromExcelFile(filepath, out pictures, out error))
        //    {
        //        lists = new ArrayList[datatable.Rows.Count];
        //        //------------DataTable转换成IList[]--------------
        //        //数据
        //        int nRow = 0;
        //        foreach (DataRow row in datatable.Rows)
        //        {
        //            lists[nRow] = new ArrayList(datatable.Columns.Count);
        //            for (int i = 0; i <= datatable.Columns.Count - 1; i++)
        //            {
        //                lists[nRow].Add(row[i]);
        //            }
        //            nRow++;
        //        }
        //        //图片
        //        for (int i = 0; i < pictures.Length; i++)
        //        {
        //            foreach (Picture picture in pictures[i])
        //            {
        //                try
        //                {
        //                    //----把图片转换成System.Drawing.Image----
        //                    //MemoryStream mstream = new MemoryStream();
        //                    //mstream.Write(picture.Data, 0, picture.Data.Length);
        //                    //System.Drawing.Image image = System.Drawing.Image.FromStream(mstream);
        //                    //----Image放入IList------
        //                    //图片有可能越界
        //                    if (picture.UpperLeftRow <= datatable.Rows.Count && picture.UpperLeftColumn <= datatable.Columns.Count)
        //                    {
        //                        lists[picture.UpperLeftRow][picture.UpperLeftColumn] = picture.Data;
        //                    }

        //                }
        //                catch (System.Exception e)
        //                {
        //                    error = error + e.Message;
        //                }

        //            }
        //        }

        //    }
        //    else
        //    {

        //        return false;
        //    }
        //    return true;
        //}

        public static bool ListsToExcelFile(string filepath, IList[] lists, out string error)
        {
            error = "";
            //----------Aspose变量初始化----------------
            Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
            Aspose.Cells.Worksheet sheet = workbook.Worksheets[0];
            Aspose.Cells.Cells cells = sheet.Cells;
            //-------------输入数据-------------
            int nRow = 0;
            sheet.Pictures.Clear();
            cells.Clear();
            foreach (IList list in lists)
            {

                for (int i = 0; i <= list.Count - 1; i++)
                {
                    try
                    {
                        System.Console.WriteLine(i.ToString() + "  " + list[i].GetType());
                        if (list[i].GetType().ToString() == "System.Drawing.Bitmap")
                        {
                            //插入图片数据
                            System.Drawing.Image image = (System.Drawing.Image)list[i];

                            MemoryStream mstream = new MemoryStream();

                            image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg);

                            sheet.Pictures.Add(nRow, i, mstream);
                        }
                        else
                        {
                            cells[nRow, i].PutValue(list[i]);
                        }
                    }
                    catch (System.Exception e)
                    {
                        error = error + e.Message;
                    }

                }

                nRow++;
            }
            //-------------保存-------------
            workbook.Save(filepath);

            return true;
        }
        #endregion

        #region Length
        /// <summary>
        /// 取字符串的长度（中文为两个字符）。
        /// </summary>
        /// <param name="strToLen">要测量的字符串。</param>
        public static Int32 Length(this String strToLen)
        {
            if (string.IsNullOrEmpty(strToLen)) return 0;
            Int32 j = System.Text.Encoding.Default.GetByteCount(strToLen);
            return j;
        }
        #endregion

        #region Substring
        /// <summary>
        /// 截取定长的字符串（中文为两个字符），并对超长字符串附加省略号。
        /// </summary>
        /// <param name="strToCut">需要截取的字符串。</param>
        /// <param name="length">要截取的长度。</param>
        public static String Substring(String strToCut, Int32 length)
        {
            return strToCut.Substring(length, "...");
        }
        /// <summary>
        /// 截取定长的字符串（中文为两个字符），并对超长字符串附加指定符号。
        /// </summary>
        /// <param name="strToCut">需要截取的字符串。</param>
        /// <param name="length">要截取的长度。</param>
        /// <param name="strOfEnd">超长部分的替换字符。</param>
        public static String Substring(this String strToCut, int length, String strOfEnd)
        {
            if (String.IsNullOrEmpty(strToCut)) return String.Empty;
            if (length <= 0) return strToCut;

            Int32 j = System.Text.Encoding.Default.GetByteCount(strToCut);
            if (j > length)
            {
                Regex r = new Regex("[\u4e00-\u9fa5]", RegexOptions.Compiled);
                Int32 i = 0;
                System.Text.StringBuilder s = new System.Text.StringBuilder();
                foreach (char c in strToCut)
                {
                    if (r.IsMatch(c.ToString()))
                        i += 2;
                    else
                        i++;
                    s.Append(c);
                    if (i >= length) break;
                }
                s.Append(" " + strOfEnd + "");
                return s.ToString();
            }
            return strToCut;
        }
        #endregion


    }
}
